using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Application.DTOs;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Infrastructure.Data.Contexts;
using UniversalAdmin.Shared.Enums;

namespace UniversalAdmin.Application.Services;

public class PermissionService : IPermissionService
{
    private readonly ApplicationDbContext _context;

    public PermissionService(ApplicationDbContext context)
    {
        _context = context;
    }

    // 获取所有权限
    public async Task<IEnumerable<PermissionDto>> GetAllPermissionsAsync()
    {
        try
        {


            // 检查数据库连接
            if (_context == null)
            {

                throw new InvalidOperationException("数据库上下文未初始化");
            }

            // 检查权限表是否存在
            var tableExists = await _context.Database.CanConnectAsync();
            if (!tableExists)
            {

                throw new InvalidOperationException("数据库连接失败");
            }



            var permissions = await _context.Permissions
                .OrderBy(p => p.SortOrder)
                .ToListAsync();



            var result = permissions.Select(p => new PermissionDto(
                p.Id,
                p.Name,
                p.Description,
                p.Resource,
                p.Action,
                p.Type,
                p.SortOrder,
                p.IsEnabled
            )).ToList();


            return result;
        }
        catch (Exception)
        {
            throw;
        }
    }

    // 根据ID获取权限
    public async Task<PermissionDto?> GetPermissionByIdAsync(Guid id)
    {
        var permission = await _context.Permissions.FindAsync(id);

        if (permission == null)
            return null;

        return new PermissionDto(
            permission.Id,
            permission.Name,
            permission.Description,
            permission.Resource,
            permission.Action,
            permission.Type,
            permission.SortOrder,
            permission.IsEnabled
        );
    }

    // 创建权限
    public async Task<PermissionDto> CreatePermissionAsync(CreatePermissionDto dto)
    {
        var permission = new Permission
        {
            Name = dto.Name,
            Description = dto.Description,
            Resource = dto.Resource,
            Action = dto.Action,
            Type = dto.Type,
            SortOrder = dto.SortOrder,
            IsEnabled = dto.IsEnabled
        };

        _context.Permissions.Add(permission);
        await _context.SaveChangesAsync();

        return new PermissionDto(
            permission.Id,
            permission.Name,
            permission.Description,
            permission.Resource,
            permission.Action,
            permission.Type,
            permission.SortOrder,
            permission.IsEnabled
        );
    }

    // 更新权限
    public async Task<PermissionDto?> UpdatePermissionAsync(Guid id, UpdatePermissionDto dto)
    {
        var permission = await _context.Permissions.FindAsync(id);

        if (permission == null)
            return null;

        permission.Name = dto.Name;
        permission.Description = dto.Description;
        permission.Resource = dto.Resource;
        permission.Action = dto.Action;
        permission.Type = dto.Type;
        permission.SortOrder = dto.SortOrder;
        permission.IsEnabled = dto.IsEnabled;

        await _context.SaveChangesAsync();

        return new PermissionDto(
            permission.Id,
            permission.Name,
            permission.Description,
            permission.Resource,
            permission.Action,
            permission.Type,
            permission.SortOrder,
            permission.IsEnabled
        );
    }

    // 删除权限
    public async Task<bool> DeletePermissionAsync(Guid id)
    {
        var permission = await _context.Permissions.FindAsync(id);

        if (permission == null)
            return false;

        // 检查是否被角色使用
        var isUsedByRoles = await _context.RolePermissions.AnyAsync(rp => rp.PermissionId == id);
        if (isUsedByRoles)
        {
            throw new InvalidOperationException("无法删除已被角色使用的权限项");
        }

        _context.Permissions.Remove(permission);
        await _context.SaveChangesAsync();

        return true;
    }

    // 获取权限树（简化为平铺列表）
    public async Task<IEnumerable<PermissionTreeDto>> GetPermissionTreeAsync()
    {
        try
        {
            var permissions = await _context.Permissions
                .Where(p => p.IsEnabled)
                .OrderBy(p => p.Resource)
                .ThenBy(p => p.SortOrder)
                .ToListAsync();

            return permissions.Select(p => new PermissionTreeDto(
                p.Id,
                p.Name,
                p.Description,
                p.Resource,
                p.Action,
                p.Type,
                p.SortOrder,
                p.IsEnabled
            ));
        }
        catch (Exception)
        {
            // 记录错误并返回空列表
            return new List<PermissionTreeDto>();
        }
    }

    // 根据角色获取权限
    public async Task<IEnumerable<PermissionDto>> GetPermissionsByRoleAsync(Guid roleId)
    {
        var permissions = await _context.RolePermissions
            .Where(rp => rp.RoleId == roleId)
            .Include(rp => rp.Permission)
            .Select(rp => rp.Permission)
            .Where(p => p != null && p.IsEnabled)
            .ToListAsync();

        return permissions.Select(p => new PermissionDto(
            p!.Id,
            p!.Name,
            p!.Description,
            p!.Resource,
            p!.Action,
            p!.Type,
            p!.SortOrder,
            p!.IsEnabled
        ));
    }

    // 批量更新权限状态
    public async Task BatchUpdateStatusAsync(List<Guid> permissionIds, bool isEnabled)
    {
        var permissions = await _context.Permissions
            .Where(p => permissionIds.Contains(p.Id))
            .ToListAsync();

        foreach (var permission in permissions)
        {
            permission.IsEnabled = isEnabled;
        }

        await _context.SaveChangesAsync();
    }

    // 获取权限统计信息
    public async Task<object> GetPermissionStatsAsync()
    {
        var totalPermissions = await _context.Permissions.CountAsync();
        var enabledPermissions = await _context.Permissions.CountAsync(p => p.IsEnabled);
        var disabledPermissions = totalPermissions - enabledPermissions;

        var permissionsByType = await _context.Permissions
            .GroupBy(p => p.Type)
            .Select(g => new { Type = g.Key, Count = g.Count() })
            .ToListAsync();

        var permissionsByResource = await _context.Permissions
            .GroupBy(p => p.Resource)
            .Select(g => new { Resource = g.Key, Count = g.Count() })
            .ToListAsync();

        return new
        {
            Total = totalPermissions,
            Enabled = enabledPermissions,
            Disabled = disabledPermissions,
            ByType = permissionsByType,
            ByResource = permissionsByResource
        };
    }
}